﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DDD.Core;

using FloatComparer = DDDTest.Helper.FloatComparer;

namespace DDDTest.Core {
    [TestClass]
    public class TestAnimationTrackSampling1 {

        private void Print (string name, float start, float end, int times, AnimationTrack track) {
            using (StreamWriter w = new StreamWriter (@name)) {
                var value = new float[track.ComponentCount];
                for (var i = 0; i < times; i++) {
                    var time = start + i * (end - start) / (float)times;
                    track.Sample (time, value);
                    w.WriteLine (time + "   " + value[0]);
                }
            }
        }

        [TestMethod]
        public void Test_Once_Step () {
            var track = new AnimationTrack (4, 1, InterpolationType.Step);
            track.SetLoopMode (LoopMode.Single);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            Print ("TestAnimationTrack_Once_Step.dat", -1, 6, 28, track);
        }

        [TestMethod]
        public void Test_Once_Linear () {
            var track = new AnimationTrack (4, 1, InterpolationType.Linear);
            track.SetLoopMode (LoopMode.Single);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            var value = new float[1];
            track.Sample (2.0f, value);

            Print ("TestAnimationTrack_Once_Linear.dat", -1, 6, 28, track);
        }

        [TestMethod]
        public void Test_Once_Spline () {
            var track = new AnimationTrack (4, 1, InterpolationType.Spline);
            track.SetLoopMode (LoopMode.Single);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            var value = new float[1];
            track.Sample (2.0f, value);

            Print ("TestAnimationTrack_Once_Linear.dat", -1, 6, 56, track);
        }

        [TestMethod]
        public void Test_Loop_Step () {
            var track = new AnimationTrack (4, 1, InterpolationType.Step);
            track.SetLoopMode (LoopMode.Loop);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            var value = new float[1];
            track.Sample (2.0f, value);

            Print ("TestAnimationTrack_Loop_Step.dat", -10, 10, 100, track);
        }

        [TestMethod]
        public void Test_Loop_Linear () {
            var track = new AnimationTrack (4, 1, InterpolationType.Linear);
            track.SetLoopMode (LoopMode.Loop);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            var value = new float[1];
            track.Sample (2.0f, value);

            Print ("TestAnimationTrack_Loop_Linear.dat", -10, 10, 100, track);
        }

        [TestMethod]
        public void Test_Loop_Spline () {
            var track = new AnimationTrack (4, 1, InterpolationType.Spline);
            track.SetLoopMode (LoopMode.Loop);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            var value = new float[1];
            track.Sample (2.0f, value);

            Print ("TestAnimationTrack_Loop_Spline.dat", -10, 10, 100, track);
        }

        [TestMethod]
        public void Test_AdditiveLoop_Step () {
            var track = new AnimationTrack (4, 1, InterpolationType.Step);
            track.SetLoopMode (LoopMode.AdditiveLoop);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            var value = new float[1];
            track.Sample (0.5f, value);

            Print ("TestAnimationTrack_AdditiveLoop_Step.dat", -10, 10, 100, track);
        }


        [TestMethod]
        public void Test_AdditiveLoop_Linear () {
            var track = new AnimationTrack (4, 1, InterpolationType.Linear);
            track.SetLoopMode (LoopMode.AdditiveLoop);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            var value = new float[1];
            track.Sample (0.5f, value);

            Print ("TestAnimationTrack_AdditiveLoop_Linear.dat", -10, 10, 100, track);
        }

        [TestMethod]
        public void Test_AdditiveLoop_Spline () {
            var track = new AnimationTrack (4, 1, InterpolationType.Spline);
            track.SetLoopMode (LoopMode.AdditiveLoop);
            track.SetKeyframe (0, 1, new[] { 1.0f });
            track.SetKeyframe (1, 2, new[] { 1.0f });
            track.SetKeyframe (2, 3, new[] { 2.0f });
            track.SetKeyframe (3, 4, new[] { 2.0f });
            track.SetDuration (5);

            var value = new float[1];
            track.Sample (0.5f, value);

            Print ("TestAnimationTrack_AdditiveLoop_Spline.dat", -10, 10, 100, track);
        }

    }
}
